package com.util;

import io.netty.buffer.ByteBuf;

import java.nio.ByteBuffer;
import java.util.Calendar;

public class MyUtil {


    /**
     * Convert byte array to Hex string whith whilespace
     * @param a
     * @return
     *
     */
    public static String byteArrayToHexString(byte[] a) {
        StringBuilder sb = new StringBuilder(a.length * 2);
        for(byte b: a)
            sb.append(String.format("%02x ", b));
        return sb.toString();
    }

    /**
     * Convert Hex string(whith while space) to byte array
     * @param s
     * @return
     */
    public static byte[] hexStringToByteArray(String s) {
        s = s.replaceAll("\\s+","");
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }


    /**
     * little-endian
     * Get Unsigned Int
     * return long
     */

    public static long getUInt32(byte[] bytes){
        if (bytes.length != 4)
            throw new IllegalArgumentException(MyUtil.class.getName() + ".getUInt32(byte[]) need 4 bytes lenth array, your input array length is " + bytes.length);
        long value = bytes[0] & 0xFF;
        value |= (bytes[1] << 8) & 0xFFFF;
        value |= (bytes[2] << 16) & 0xFFFFFF;
        value |= (bytes[3] << 24) & 0xFFFFFFFF;
        return value;
    }



    // big-endian
    public static int getUInt16(byte[] bytes){
        if (bytes.length != 2)
            throw new IllegalArgumentException(MyUtil.class.getName() + ".getUInt16(byte[]) need 2 bytes lenth array, your input array length is " + bytes.length);
        int value = bytes[1] & 0xFF;
        value |= (bytes[0] << 8) & 0xFFFF;
        return value;

    }

    /**
     * Padding left for a {@inputNum} with {@paddingChar} to a {@totalWith} String
     * @param inputNum
     * @param totalWidth
     * @param paddingChar
     * @return
     */
    public static String padLeft(long inputNum, int totalWidth, char paddingChar){
        StringBuilder sb = new StringBuilder(String.valueOf(inputNum));
        if (sb.length() > totalWidth)
        {
            sb.setLength(totalWidth);
        }
        else if (sb.length() < totalWidth){
            while(sb.length() != totalWidth)
                sb.insert(0, paddingChar);
        }
        return sb.toString();
    }


    /**
     * Checkthrough XOR
     * @param in
     * @return
     */
    public static boolean xorCheck(ByteBuf in){
        byte result = xorResult(in);
        if (result == 0)
            return true;
        else
            return false;
    }

    public static byte xorResult(ByteBuf in){
        byte result = in.getByte(in.readerIndex());
        for(int i = in.readerIndex() + 1; i <in.writerIndex(); ++i)
            result ^= in.getByte(i);
        return result;
    }


    public static byte[] intToUInt16Bytes(int value){
        byte[] ret = ByteBuffer.allocate(4).putInt(value).array();
        return new byte[]{ret[2], ret[3]};
    }

    public static byte[] byteArrayConcat(byte[] a, byte[] b){
        byte[] c = new byte[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }

    /**
     * @param setBefore
     * @param bitIndex index direction from left to right,range in [1, 8], leftmost 1, rightmost 8
     * @return
     * PS: 逻辑/算术右移都会将byte类型自动转换成int进行右移操作
     */
    public static byte setBitAt(byte setBefore, int bitIndex){
        int mask = 0b00000001;
        int a = ( mask << (bitIndex -1));
        return (byte)(setBefore | a);
    }

    public static void printMsg(String msg, ByteBuf in){
        byte[] out = new byte[in.readableBytes()];
        in.getBytes(in.readerIndex(), out,0,out.length);

        System.out.println(Calendar.getInstance().getTime() + " " +msg + ": " + MyUtil.byteArrayToHexString(out));
    }
}
